/****************************************************************************
 *  _____       ______  _____
 * |_   _|     |  ____|/ ____|
 *   | |  _ __ | |__  | (___    Institute of Embedded Systems
 *   | | | '_ \|  __|  \___ \   Zürcher Hochschule für Angewandte
 *  _| |_| | | | |____ ____) |  Wissenschaften
 * |_____|_| |_|______|_____/   8401 Winterthur, Switzerland
 *
 ****************************************************************************
 *
 * @version $Rev: 69 $
 * @author  $Author: bacr $
 * @date    $Date: 2013-06-04 18:10:25 +0200 (mar., 04 juin 2013) $
 *
 ***************************************************************************/

#ifndef __UDP_PACKET_H__
#define __UDP_PACKET_H__

typedef struct udp_header_t udp_header_t;
typedef struct udp_packet_t udp_packet_t;

#define UDP_PACKET(obj) ((udp_packet_t *) obj)

/* length on the wire! */
#define UDP_PACKET_LEN                      8

#define UDP_PACKET_OFFSET_SRC_PORT          0
#define UDP_PACKET_OFFSET_DEST_PORT         2
#define UDP_PACKET_OFFSET_LEN               4
#define UDP_PACKET_OFFSET_CHECKSUM          6

#define UDP_PACKET_PSEUDO_IPV4_SRC          12
#define UDP_PACKET_PSEUDO_IPV4_DEST         8
#define UDP_PACKET_PSEUDO_IPV4_ZERO         4
#define UDP_PACKET_PSEUDO_IPV4_PROTOCOL     3
#define UDP_PACKET_PSEUDO_IPV4_LEN          2

#define UDP_PACKET_PSEUDO_IPV6_SRC          40
#define UDP_PACKET_PSEUDO_IPV6_DEST         24
#define UDP_PACKET_PSEUDO_IPV6_LEN          8
#define UDP_PACKET_PSEUDO_IPV6_ZERO         4
#define UDP_PACKET_PSEUDO_IPV6_NEXT_HEADER  1

#define UDP_PACKET_PORT_PTP2_EVENT          319
#define UDP_PACKET_PORT_PTP2_GENERAL        320

/* network byte order */
#define UDP_HEADER              \
    uint16_t        src_port;   \
    uint16_t        dest_port;  \
    uint16_t        len;        \
    uint16_t        checksum;

/**
 * @struct udp_header_t
 * @brief  UDP header
 * @see    udp_packet_t
 *
 * @var    udp_header_t::src_port
 * @brief  Source port
 *
 * @var    udp_header_t::dest_port
 * @brief  Destination port
 *
 * @var    udp_header_t::len
 * @brief  Length of UDP header and payload
 *
 * @var    udp_header_t::checksum
 * @brief  Checksum over pseudo header (IP lite), UDP header and payload
 */
struct udp_header_t {
    UDP_HEADER
};

/**
 * @brief  UDP packet
 * @see    udp_header_t
 */
struct udp_packet_t {
    object_t            obj;
    info_header_t       info;
    ethernet_header_t   ether;      /**< @brief Ethernet header */
    ip_header_t         ip;         /**< @brief IP Header */
    UDP_HEADER
};

uint32_t    udp_packet_encode(udp_packet_t *this, raw_packet_t *raw_packet, uint32_t udp_offset);
void        udp_packet_decode(udp_packet_t *this, raw_packet_t *raw_packet, uint32_t udp_offset);

#endif

